package main.test.sparklingGraphAPI

import main.test.sparklingGraphAPI.LoadingGraph.ctx
import ml.sparkling.graph.loaders.csv.GraphFromCsv.LoaderParameters.{Delimiter, Quotation}
import spire.compat.integral
//import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap
import ml.sparkling.graph.api.loaders.GraphLoading.LoadGraph
import ml.sparkling.graph.loaders.csv.GraphFromCsv.CSV
import ml.sparkling.graph.operators.OperatorsDSL._
import org.apache.spark.graphx.Graph


object GraphMeasure {
  def main(args: Array[String]): Unit = {
    // Using SparklingGraph you can you utilize multiple well-known measures for graphs.
    //Graph measures API
    /**
     * Graph measures
     * each graph measure extends GraphMeasure trait, defining
     * what kind of value will be returned for whole graph
     * Vertex measures.
     * For main part of measures that will be a single number (like Double )
     * but for some of them  a tupple  (or other data type) can be returned
     * (like(Double,Double)). Each measure defines also implicit methods for graph..
     * thanks to what you code will be more readable, and you will develop
     * your experiments faster.
     *
     * Measures accepts VertexMeasureConfiguration in order to configure computation
     * process. You can set following parameters:
     * BucketSieProvider -- used in more complex computations in order to
     * divide data into buckets.
     * treatAsUndirected:Boolean -- graph will be treated as undirected during computations
     *
     *
     * Edges measures
     * Each edge measure extends EdgeMeasure trait, defining what kind of value
     * will be returned for each edge, and what kind of data is expected for each vertex.
     * Each measure defines also implicit methods for graph, thanks to what your code will be more readable, and you will develop your experiments faster.
     *
     * Measures accepts parameters:
     * treatAsUndirected:Boolean -- graph will be treated as undirected during computations
     * Beside defining methods for computing measure for whole graph,
     * method (computeValues) for single edge is also present.
     *
     *
     */

    /**
     * Measures
     * you can use following measures:
     * Vertex measures:
     * 1 Closeness centrality
     * 2 Eigenvector centrality
     * 3 HITS
     * 4 Degree centrality
     * 5 Neighborhood Connectivity
     * 6 Vertex Embeddedness
     * 7 Local clustering coefficient
     *
     * Graph measures:
     * 1 Freeman's network centrality
     * 2 Modularity
     * Edges measures:
     * 1 Adamic / Adar
     * 2 Common Neighbours
     * All above refer to :
     * https://sparkling-graph.readthedocs.io/en/latest/measures.html
     *
     *
     */

    //Closeness centrality
    /**
     * Closeness centrality measure is defined as
     * inverted sum of distances (d(y,x)) from given
     * node to all other nodes.
     * Distance is defined as length of shortest path.
     * 它被定义为从给定节点到其他节点的距离d(y,x)的和的倒数。
     * 节点之间的距离则是最短路径的长度。
     * c(x) = 1/sum(d(y,x)) ，当然我觉得距离倒数之和也挺好的。
     *
     * Measure can be understood as  how far away from other node  given
     * node is located. For further informations please refer to :
     * The centrality index of a graph.Psychometrika
     * For memory consumption optimization, informations about distances are held in memory efficient
     * implementations of collections
     * available in fastutil library
     *
     */


    val filePath="data/your_graph_path.csv"

    val graph2: Graph[String,String] =LoadGraph.from(CSV(filePath)).load()
//    val filePath2="data/your_graph_path2.csv"
//    val graph2: Graph[String, String] =LoadGraph.from(CSV(filePath2)).using(Delimiter(";")).using(Quotation("'")).load()

    val     graph3   =  graph2.mapEdges(x=>1.toLong).mapVertices((_, x)=>x.toDouble)
    //    val graph2   = graph.mapEdges( x => (1.0).toLong)

//    graph2.vertices.foreach(x=>println(x))

    /**
     * Error!!!
     * java.lang.NoSuchMethodError: it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap.get(Ljava/lang/Long;)Ljava/lang/Double;
     * at ml.sparkling.graph.operators.algorithms.shortestpaths.pathprocessors.fastutils.FastUtilWithDistance$$anonfun$mergePathContainers$1.apply(FastUtilWithDistance.scala:32)
     */
        val centralityGraph: Graph[Double, _] = graph3.closenessCentrality()
////
//    centralityGraph.vertices.foreach(x=>println(x))








  }


}
